home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / fax / pmlfax.py < prev    next >
Text File  |  2009-10-09  |  43KB  |  1,027 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import sys
  24. import os
  25. import os.path
  26. import struct
  27. import time
  28. import threading
  29.  
  30. # Local
  31. from base.g import *
  32. from base.codes import *
  33. from base import device, utils, pml, codes
  34. from prnt import cups
  35. from fax import *
  36.  
  37.  
  38. # **************************************************************************** #
  39.  
  40. # Page flags
  41. PAGE_FLAG_NONE = 0x00
  42. PAGE_FLAG_NEW_PAGE = 0x01
  43. PAGE_FLAG_END_PAGE = 0x02
  44. PAGE_FLAG_NEW_DOC = 0x04
  45. PAGE_FLAG_END_DOC = 0x08
  46. PAGE_FLAG_END_STREAM = 0x10
  47.  
  48. MAJOR_VER = 2
  49. MINOR_VER = 0
  50.  
  51. MFPDTF_RASTER_BITMAP  = 0 # Not used
  52. MFPDTF_RASTER_GRAYMAP = 1 # Not used
  53. MFPDTF_RASTER_MH      = 2 # OfficeJets B&W Fax
  54. MFPDTF_RASTER_MR      = 3 # Not used
  55. MFPDTF_RASTER_MMR     = 4 # LaserJets B&W Fax
  56. MFPDTF_RASTER_RGB     = 5 # Not used
  57. MFPDTF_RASTER_YCC411  = 6 # Not used
  58. MFPDTF_RASTER_JPEG    = 7 # Color Fax
  59. MFPDTF_RASTER_PCL     = 8 # Not used
  60. MFPDTF_RASTER_NOT     = 9 # Not used
  61.  
  62. # Data types for FH
  63. DT_UNKNOWN       = 0
  64. DT_FAX_IMAGES    = 1
  65. DT_SCANNED_IMAGES= 2
  66. DT_DIAL_STRINGS  = 3
  67. DT_DEMO_PAGES    = 4
  68. DT_SPEED_DIALS   = 5
  69. DT_FAX_LOGS      = 6
  70. DT_CFG_PARMS     = 7
  71. DT_LANG_STRS     = 8
  72. DT_JUNK_FAX_CSIDS= 9
  73. DT_REPORT_STRS   = 10
  74. DT_FONTS         = 11
  75. DT_TTI_BITMAP    = 12
  76. DT_COUNTERS      = 13
  77. DT_DEF_PARMS     = 14
  78. DT_SCAN_OPTIONS  = 15
  79. DT_FW_JOB_TABLE  = 17
  80.  
  81. # Raster data record types
  82. RT_START_PAGE = 0
  83. RT_RASTER = 1
  84. RT_END_PAGE = 2
  85.  
  86. # FH
  87. FIXED_HEADER_SIZE = 8
  88.  
  89. # Variants
  90. IMAGE_VARIANT_HEADER_SIZE = 10
  91. DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
  92. FAX_IMAGE_VARIANT_HEADER_SIZE = 74
  93.  
  94. # Data records
  95. SOP_RECORD_SIZE = 36
  96. RASTER_RECORD_SIZE = 4
  97. EOP_RECORD_SIZE = 12
  98. DIAL_STRING_RECORD_SIZE = 51
  99.  
  100. # Page flags
  101. PAGE_FLAG_NEW_PAGE = 0x01
  102. PAGE_FLAG_END_PAGE = 0x02
  103. PAGE_FLAG_NEW_DOC = 0x04
  104. PAGE_FLAG_END_DOC = 0x08
  105. PAGE_FLAG_END_STREAM = 0x10
  106.  
  107. # Fax data variant header data source
  108. SRC_UNKNOWN = 0
  109. SRC_HOST = 2
  110. SRC_SCANNER = 5
  111. SRC_HOST_THEN_SCANNER = 6
  112. SRC_SCANNER_THEN_HOST = 7
  113.  
  114. # Fax data variant header TTI header control
  115. TTI_NONE = 0
  116. TTI_PREPENDED_TO_IMAGE = 1
  117. TTI_OVERLAYED_ON_IMAGE = 2
  118.  
  119. RASTER_DATA_SIZE = 504
  120.  
  121.  
  122.  
  123. # **************************************************************************** #
  124. class PMLFaxDevice(FaxDevice):
  125.  
  126.     def __init__(self, device_uri=None, printer_name=None,
  127.                  callback=None,
  128.                  fax_type=FAX_TYPE_NONE,
  129.                  disable_dbus=False):
  130.  
  131.         FaxDevice.__init__(self, device_uri,
  132.                            printer_name,
  133.                            callback, fax_type,
  134.                            disable_dbus)
  135.  
  136.         self.send_fax_thread = None
  137.         self.upload_log_thread = None
  138.  
  139.  
  140.     def setPhoneNum(self, num):
  141.         return self.setPML(pml.OID_FAX_LOCAL_PHONE_NUM, str(num))
  142.  
  143.     def getPhoneNum(self):
  144.         return utils.printable(str(self.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)[1]))
  145.  
  146.     phone_num = property(getPhoneNum, setPhoneNum, doc="OID_FAX_LOCAL_PHONE_NUM")
  147.  
  148.  
  149.     def setStationName(self, name):
  150.         return self.setPML(pml.OID_FAX_STATION_NAME, str(name))
  151.  
  152.     def getStationName(self):
  153.         return utils.printable(str(self.getPML(pml.OID_FAX_STATION_NAME)[1]))
  154.  
  155.     station_name = property(getStationName, setStationName, doc="OID_FAX_STATION_NAME")
  156.  
  157.     def setDateAndTime(self):
  158.         t = time.localtime()
  159.         p = struct.pack("BBBBBBB", t[0]-2000, t[1], t[2], t[6]+1, t[3], t[4], t[5])
  160.         log.debug(repr(p))
  161.         return self.setPML(pml.OID_DATE_AND_TIME, p)
  162.  
  163.     def uploadLog(self):
  164.         if not self.isUloadLogActive():
  165.             self.upload_log_thread = UploadLogThread(self)
  166.             self.upload_log_thread.start()
  167.             return True
  168.         else:
  169.             return False
  170.  
  171.     def isUploadLogActive(self):
  172.         if self.upload_log_thread is not None:
  173.             return self.upload_log_thread.isAlive()
  174.         else:
  175.             return False
  176.  
  177.     def waitForUploadLogThread(self):
  178.         if self.upload_log_thread is not None and \
  179.             self.upload_log_thread.isAlive():
  180.  
  181.             self.upload_log_thread.join()
  182.  
  183.     def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='',
  184.                   cover_func=None, preserve_formatting=False, printer_name='',
  185.                   update_queue=None, event_queue=None):
  186.  
  187.         if not self.isSendFaxActive():
  188.  
  189.             self.send_fax_thread = PMLFaxSendThread(self, self.service, phone_num_list, fax_file_list,
  190.                                                     cover_message, cover_re, cover_func,
  191.                                                     preserve_formatting,
  192.                                                     printer_name, update_queue,
  193.                                                     event_queue)
  194.  
  195.             self.send_fax_thread.start()
  196.             return True
  197.         else:
  198.             return False
  199.  
  200.  
  201.  
  202. # **************************************************************************** #
  203. class PMLUploadLogThread(threading.Thread):
  204.     def __init__(self, dev):
  205.         threading.Thread.__init__(self)
  206.         self.dev = dev
  207.  
  208.  
  209.     def run(self):
  210.         STATE_DONE = 0
  211.         STATE_ABORT = 10
  212.         STATE_SUCCESS = 20
  213.         STATE_BUSY = 25
  214.         STATE_DEVICE_OPEN = 28
  215.         STATE_CHECK_IDLE = 30
  216.         STATE_REQUEST_START = 40
  217.         STATE_WAIT_FOR_ACTIVE = 50
  218.         STATE_UPLOAD_DATA = 60
  219.         STATE_DEVICE_CLOSE = 70
  220.  
  221.         state = STATE_CHECK_IDLE
  222.  
  223.         while state != STATE_DONE: # --------------------------------- Log upload state machine
  224.             if state == STATE_ABORT:
  225.                 pass
  226.             elif state == STATE_SUCCESS:
  227.                 pass
  228.             elif state == STATE_BUSY:
  229.                 pass
  230.  
  231.             elif state == STATE_DEVICE_OPEN: # --------------------------------- Open device (28)
  232.                 state = STATE_REQUEST_START
  233.                 try:
  234.                     self.dev.open()
  235.                 except Error, e:
  236.                     log.error("Unable to open device (%s)." % e.msg)
  237.                     state = STATE_ERROR
  238.                 else:
  239.                     try:
  240.                         dev.setPML(pml.OID_UPLOAD_TIMEOUT, pml.DEFAULT_UPLOAD_TIMEOUT)
  241.                     except Error:
  242.                         state = STATE_ERROR
  243.  
  244.             elif state == STATE_CHECK_IDLE: # --------------------------------- Check idle (30)
  245.                 state = STATE_REQUEST_START
  246.                 ul_state = self.getCfgUploadState()
  247.  
  248.                 if ul_state != pml.UPDN_STATE_IDLE:
  249.                     state = STATE_BUSY
  250.  
  251.  
  252.             elif state == STATE_REQUEST_START: # --------------------------------- Request start (40)
  253.                 state = STATE_WAIT_FOR_ACTIVE
  254.                 self.dev.setPML(pml.OID_FAX_CFG_UPLOAD_DATA_TYPE, pml.FAX_CFG_UPLOAD_DATA_TYPE_FAXLOGS)
  255.                 self.dev.setPML(pml.OID_DEVICE_CFG_UPLOAD, pml.UPDN_STATE_REQSTART)
  256.  
  257.             elif state == STATE_WAIT_FOR_ACTIVE: # --------------------------------- Wait for active state (50)
  258.                 state = STATE_UPLOAD_DATA
  259.  
  260.                 tries = 0
  261.                 while True:
  262.                     tries += 1
  263.                     ul_state = self.getCfgUploadState()
  264.  
  265.                     if ul_state == pml.UPDN_STATE_XFERACTIVE:
  266.                         break
  267.  
  268.                     if ul_state in (pml.UPDN_STATE_ERRORABORT, pml.UPDN_STATE_XFERDONE):
  269.                         log.error("Cfg upload aborted!")
  270.                         state = STATE_ERROR
  271.                         break
  272.  
  273.                     if tries > 10:
  274.                         state = STATE_ERROR
  275.                         log.error("Unable to get into active state!")
  276.                         break
  277.  
  278.                     time.sleep(0.5)
  279.  
  280.             elif state == STATE_UPLOAD_DATA: # --------------------------------- Upload log data (60)
  281.                 pass
  282.  
  283.             elif state == STATE_DEVICE_CLOSE: # --------------------------------- Close device (70)
  284.                 self.dev.close()
  285.  
  286.  
  287.  
  288. # **************************************************************************** #
  289. class PMLFaxSendThread(FaxSendThread):
  290.     def __init__(self, dev, service, phone_num_list, fax_file_list,
  291.                  cover_message='', cover_re='', cover_func=None, preserve_formatting=False,
  292.                  printer_name='', update_queue=None, event_queue=None):
  293.  
  294.         FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list,
  295.              cover_message, cover_re, cover_func, preserve_formatting,
  296.              printer_name, update_queue, event_queue)
  297.  
  298.  
  299.     def run(self):
  300.         #results = {} # {'file' : error_code,...}
  301.  
  302.         STATE_DONE = 0
  303.         STATE_ABORTED = 10
  304.         STATE_SUCCESS = 20
  305.         STATE_BUSY = 25
  306.         STATE_READ_SENDER_INFO = 30
  307.         STATE_PRERENDER = 40
  308.         STATE_COUNT_PAGES = 50
  309.         STATE_NEXT_RECIPIENT = 60
  310.         STATE_COVER_PAGE = 70
  311.         STATE_SINGLE_FILE = 80
  312.         STATE_MERGE_FILES = 90
  313.         STATE_SINGLE_FILE = 100
  314.         STATE_SEND_FAX = 110
  315.         STATE_CLEANUP = 120
  316.         STATE_ERROR = 130
  317.  
  318.         next_recipient = self.next_recipient_gen()
  319.  
  320.         state = STATE_READ_SENDER_INFO
  321.         self.rendered_file_list = []
  322.  
  323.         while state != STATE_DONE: # --------------------------------- Fax state machine
  324.             if self.check_for_cancel():
  325.                 state = STATE_ABORTED
  326.  
  327.             log.debug("STATE=(%d, 0, 0)" % state)
  328.  
  329.             if state == STATE_ABORTED: # --------------------------------- Aborted (10, 0, 0)
  330.                 log.error("Aborted by user.")
  331.                 self.write_queue((STATUS_IDLE, 0, ''))
  332.                 state = STATE_CLEANUP
  333.  
  334.  
  335.             elif state == STATE_SUCCESS: # --------------------------------- Success (20, 0, 0)
  336.                 log.debug("Success.")
  337.                 self.write_queue((STATUS_COMPLETED, 0, ''))
  338.                 state = STATE_CLEANUP
  339.  
  340.  
  341.             elif state == STATE_ERROR: # --------------------------------- Error (130, 0, 0)
  342.                 log.error("Error, aborting.")
  343.                 self.write_queue((STATUS_ERROR, 0, ''))
  344.                 state = STATE_CLEANUP
  345.  
  346.  
  347.             elif state == STATE_BUSY: # --------------------------------- Busy (25, 0, 0)
  348.                 log.error("Device busy, aborting.")
  349.                 self.write_queue((STATUS_BUSY, 0, ''))
  350.                 state = STATE_CLEANUP
  351.  
  352.  
  353.             elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info (30, 0, 0)
  354.                 log.debug("%s State: Get sender info" % ("*"*20))
  355.                 state = STATE_PRERENDER
  356.                 try:
  357.                     try:
  358.                         self.dev.open()
  359.                     except Error, e:
  360.                         log.error("Unable to open device (%s)." % e.msg)
  361.                         state = STATE_ERROR
  362.                     else:
  363.                         try:
  364.                             self.sender_name = self.dev.station_name
  365.                             log.debug("Sender name=%s" % self.sender_name)
  366.                             self.sender_fax = self.dev.phone_num
  367.                             log.debug("Sender fax=%s" % self.sender_fax)
  368.                         except Error:
  369.                             log.error("PML get failed!")
  370.                             state = STATE_ERROR
  371.  
  372.                 finally:
  373.                     self.dev.close()
  374.  
  375.  
  376.             elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files (40, 0, 0)
  377.                 log.debug("%s State: Pre-render non-G3 files" % ("*"*20))
  378.                 state = self.pre_render(STATE_COUNT_PAGES)
  379.  
  380.  
  381.             elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count (50, 0, 0)
  382.                 log.debug("%s State: Get total page count" % ("*"*20))
  383.                 state = self.count_pages(STATE_NEXT_RECIPIENT)
  384.  
  385.  
  386.             elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients (60, 0, 0)
  387.                 log.debug("%s State: Next recipient" % ("*"*20))
  388.                 state = STATE_COVER_PAGE
  389.  
  390.                 try:
  391.                     recipient = next_recipient.next()
  392.                     #print recipient
  393.                     log.debug("Processing for recipient %s" % recipient['name'])
  394.  
  395.                     self.write_queue((STATUS_SENDING_TO_RECIPIENT, 0, recipient['name']))
  396.  
  397.                 except StopIteration:
  398.                     state = STATE_SUCCESS
  399.                     log.debug("Last recipient.")
  400.                     continue
  401.  
  402.                 self.recipient_file_list = self.rendered_file_list[:]
  403.  
  404.  
  405.             elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page (70, 0, 0)
  406.                 log.debug("%s State: Render cover page" % ("*"*20))
  407.                 state = self.cover_page(recipient)
  408.  
  409.  
  410.             elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) (80, 0, 0)
  411.                 log.debug("%s State: Handle single file" % ("*"*20))
  412.                 state = self.single_file(STATE_SEND_FAX)
  413.  
  414.             elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files (90, 0, 0)
  415.                 log.debug("%s State: Merge multiple files" % ("*"*20))
  416.                 state = self.merge_files(STATE_SEND_FAX)
  417.  
  418.             elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine (110, 0, 0)
  419.                 log.debug("%s State: Send fax" % ("*"*20))
  420.                 state = STATE_NEXT_RECIPIENT
  421.  
  422.                 FAX_SEND_STATE_DONE = 0
  423.                 FAX_SEND_STATE_ABORT = 10
  424.                 FAX_SEND_STATE_ERROR = 20
  425.                 FAX_SEND_STATE_BUSY = 25
  426.                 FAX_SEND_STATE_SUCCESS = 30
  427.                 FAX_SEND_STATE_DEVICE_OPEN = 40
  428.                 FAX_SEND_STATE_SET_TOKEN = 50
  429.                 FAX_SEND_STATE_EARLY_OPEN = 60
  430.                 FAX_SEND_STATE_SET_PARAMS = 70
  431.                 FAX_SEND_STATE_CHECK_IDLE = 80
  432.                 FAX_SEND_STATE_START_REQUEST = 90
  433.                 FAX_SEND_STATE_LATE_OPEN = 100
  434.                 FAX_SEND_STATE_SEND_DIAL_STRINGS = 110
  435.                 FAX_SEND_STATE_SEND_FAX_HEADER = 120
  436.                 FAX_SEND_STATE_SEND_PAGES = 130
  437.                 FAX_SEND_STATE_SEND_END_OF_STREAM = 140
  438.                 FAX_SEND_STATE_WAIT_FOR_COMPLETE = 150
  439.                 FAX_SEND_STATE_RESET_TOKEN = 160
  440.                 FAX_SEND_STATE_CLOSE_SESSION = 170
  441.  
  442.                 monitor_state = False
  443.                 error_state = pml.DN_ERROR_NONE
  444.                 fax_send_state = FAX_SEND_STATE_DEVICE_OPEN
  445.  
  446.                 while fax_send_state != FAX_SEND_STATE_DONE:
  447.  
  448.                     if self.check_for_cancel():
  449.                         log.error("Fax send aborted.")
  450.                         fax_send_state = FAX_SEND_STATE_ABORT
  451.  
  452.                     if monitor_state:
  453.                         fax_state = self.getFaxDownloadState()
  454.                         if not fax_state in (pml.UPDN_STATE_XFERACTIVE, pml.UPDN_STATE_XFERDONE):
  455.                             log.error("D/L error state=%d" % fax_state)
  456.                             fax_send_state = FAX_SEND_STATE_ERROR
  457.                             state = STATE_ERROR
  458.  
  459.                     log.debug("STATE=(%d, %d, 0)" % (STATE_SEND_FAX, fax_send_state))
  460.  
  461.                     if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort (110, 10, 0)
  462.                         # TODO: Set D/L state to ???
  463.                         monitor_state = False
  464.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  465.                         state = STATE_ABORTED
  466.  
  467.                     elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error (110, 20, 0)
  468.                         log.error("Fax send error.")
  469.                         error_state = self.getFaxDownloadError()
  470.                         log.debug("Error State=%d (%s)" % (error_state, pml.DN_ERROR_STR.get(error_state, "Unknown")))
  471.                         monitor_state = False
  472.  
  473.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  474.                         state = STATE_ERROR
  475.  
  476.                     elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy (110, 25, 0)
  477.                         log.error("Fax device busy.")
  478.                         monitor_state = False
  479.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  480.                         state = STATE_BUSY
  481.  
  482.                     elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success (110, 30, 0)
  483.                         log.debug("Fax send success.")
  484.                         monitor_state = False
  485.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  486.                         state = STATE_NEXT_RECIPIENT
  487.  
  488.                     elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open (110, 40, 0)
  489.                         log.debug("%s State: Open device" % ("*"*20))
  490.                         fax_send_state = FAX_SEND_STATE_SET_TOKEN
  491.                         try:
  492.                             self.dev.open()
  493.                         except Error, e:
  494.                             log.error("Unable to open device (%s)." % e.msg)
  495.                             fax_send_state = FAX_SEND_STATE_ERROR
  496.                         else:
  497.                             if self.dev.device_state == DEVICE_STATE_NOT_FOUND:
  498.                                 fax_send_state = FAX_SEND_STATE_ERROR
  499.  
  500.                     elif fax_send_state == FAX_SEND_STATE_SET_TOKEN: # -------------- Acquire fax token (110, 50, 0)
  501.                         log.debug("%s State: Acquire fax token" % ("*"*20))
  502.                         try:
  503.                             result_code, token = self.dev.getPML(pml.OID_FAX_TOKEN)
  504.                         except Error:
  505.                             log.debug("Unable to acquire fax token (1).")
  506.                             fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  507.                         else:
  508.                             if result_code > pml.ERROR_MAX_OK:
  509.                                 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  510.                                 log.debug("Skipping token acquisition.")
  511.                             else:
  512.                                 token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
  513.                                 log.debug("Setting token: %s" % token)
  514.                                 try:
  515.                                     self.dev.setPML(pml.OID_FAX_TOKEN, token)
  516.                                 except Error:
  517.                                     log.error("Unable to acquire fax token (2).")
  518.                                     fax_send_state = FAX_SEND_STATE_ERROR
  519.                                 else:
  520.                                     result_code, check_token = self.dev.getPML(pml.OID_FAX_TOKEN)
  521.  
  522.                                     if check_token == token:
  523.                                         fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  524.                                     else:
  525.                                         log.error("Unable to acquire fax token (3).")
  526.                                         fax_send_state = FAX_SEND_STATE_ERROR
  527.  
  528.  
  529.                     elif fax_send_state == FAX_SEND_STATE_EARLY_OPEN: # -------------- Early open (newer models) (110, 60, 0)
  530.                         log.debug("%s State: Early open" % ("*"*20))
  531.                         fax_send_state = FAX_SEND_STATE_CHECK_IDLE
  532.  
  533.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: # newer
  534.                             log.debug("Opening fax channel.")
  535.                             try:
  536.                                 self.dev.openFax()
  537.                             except Error, e:
  538.                                 log.error("Unable to open channel (%s)." % e.msg)
  539.                                 fax_send_state = FAX_SEND_STATE_ERROR
  540.                         else:
  541.                             log.debug("Skipped.")
  542.  
  543.  
  544.                     elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle (110, 80, 0)
  545.                         log.debug("%s State: Check idle" % ("*"*20))
  546.                         fax_send_state = FAX_SEND_STATE_START_REQUEST
  547.  
  548.                         dl_state = self.getFaxDownloadState()
  549.                         tx_status = self.getFaxJobTxStatus()
  550.                         rx_status = self.getFaxJobRxStatus()
  551.  
  552.                         if ((dl_state == pml.UPDN_STATE_IDLE or \
  553.                             dl_state == pml.UPDN_STATE_ERRORABORT or \
  554.                             dl_state == pml.UPDN_STATE_XFERDONE) and \
  555.                             (tx_status == pml.FAXJOB_TX_STATUS_IDLE or tx_status == pml.FAXJOB_TX_STATUS_DONE) and \
  556.                             (rx_status == pml.FAXJOB_RX_STATUS_IDLE or rx_status == pml.FAXJOB_RX_STATUS_DONE)):
  557.  
  558.                             # xwas if state == pml.UPDN_STATE_IDLE:
  559.                             if dl_state == pml.UPDN_STATE_IDLE:
  560.                                 log.debug("Starting in idle state")
  561.                             else:
  562.                                 log.debug("Resetting to idle...")
  563.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  564.                                 time.sleep(0.5)
  565.                         else:
  566.                             fax_send_state = FAX_SEND_STATE_BUSY
  567.  
  568.                     elif fax_send_state == FAX_SEND_STATE_START_REQUEST: # -------------- Request fax start (110, 90, 0)
  569.                         log.debug("%s State: Request start" % ("*"*20))
  570.                         fax_send_state = FAX_SEND_STATE_SET_PARAMS
  571.  
  572.                         dl_state = self.getFaxDownloadState()
  573.  
  574.                         if dl_state == pml.UPDN_STATE_IDLE:
  575.                             log.debug("Try: 0")
  576.                             log.debug("Setting to up/down state request start...")
  577.                             self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  578.                             time.sleep(1)
  579.  
  580.                             log.debug("Waiting for active state...")
  581.                             i = 1
  582.  
  583.                             while i < 10:
  584.                                 log.debug("Try: %d" % i)
  585.                                 try:
  586.                                     dl_state = self.getFaxDownloadState()
  587.                                 except Error:
  588.                                     log.error("PML/SNMP error")
  589.                                     fax_send_state = FAX_SEND_STATE_ERROR
  590.                                     break
  591.  
  592.                                 if dl_state == pml.UPDN_STATE_XFERACTIVE:
  593.                                     break
  594.  
  595.                                 time.sleep(1)
  596.                                 log.debug("Setting to up/down state request start...")
  597.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  598.  
  599.                                 i += 1
  600.  
  601.                             else:
  602.                                 log.error("Could not get into active state!")
  603.                                 fax_send_state = FAX_SEND_STATE_BUSY
  604.  
  605.                             monitor_state = True
  606.  
  607.                         else:
  608.                             log.error("Could not get into idle state!")
  609.                             fax_send_state = FAX_SEND_STATE_BUSY
  610.  
  611.  
  612.                     elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params (110, 70, 0)
  613.                         log.debug("%s State: Set params" % ("*"*20))
  614.                         fax_send_state = FAX_SEND_STATE_LATE_OPEN
  615.  
  616.                         try:
  617.                             self.dev.setPML(pml.OID_DEV_DOWNLOAD_TIMEOUT, pml.DEFAULT_DOWNLOAD_TIMEOUT)
  618.                             self.dev.setPML(pml.OID_FAXJOB_TX_TYPE, pml.FAXJOB_TX_TYPE_HOST_ONLY)
  619.                             log.debug("Setting date and time on device.")
  620.                             self.dev.setDateAndTime()
  621.                         except Error, e:
  622.                             log.error("PML/SNMP error (%s)" % e.msg)
  623.                             fax_send_state = FAX_SEND_STATE_ERROR
  624.  
  625.  
  626.                     elif fax_send_state == FAX_SEND_STATE_LATE_OPEN: # -------------- Late open (older models) (110, 100, 0)
  627.                         log.debug("%s State: Late open" % ("*"*20))
  628.                         fax_send_state = FAX_SEND_STATE_SEND_DIAL_STRINGS
  629.  
  630.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: # older
  631.                             log.debug("Opening fax channel.")
  632.                             try:
  633.                                 self.dev.openFax()
  634.                             except Error:
  635.                                 log.error("Unable to open channel.")
  636.                                 fax_send_state = FAX_SEND_STATE_ERROR
  637.                         else:
  638.                             log.debug("Skipped.")
  639.  
  640.  
  641.                     elif fax_send_state == FAX_SEND_STATE_SEND_DIAL_STRINGS: # -------------- Dial strings (110, 110, 0)
  642.                         log.debug("%s State: Send dial strings" % ("*"*20))
  643.                         fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER
  644.  
  645.                         log.debug("Dialing: %s" % recipient['fax'])
  646.  
  647.                         log.debug("Sending dial strings...")
  648.                         self.create_mfpdtf_fixed_header(DT_DIAL_STRINGS, True,
  649.                             PAGE_FLAG_NEW_DOC | PAGE_FLAG_END_DOC | PAGE_FLAG_END_STREAM) # 0x1c on Windows, we were sending 0x0c
  650.                         #print recipient
  651.                         dial_strings = recipient['fax'].encode('ascii')
  652.                         log.debug(repr(dial_strings))
  653.                         self.create_mfpdtf_dial_strings(dial_strings)
  654.  
  655.                         try:
  656.                             self.write_stream()
  657.                         except Error:
  658.                             log.error("Channel write error.")
  659.                             fax_send_state = FAX_SEND_STATE_ERROR
  660.  
  661.  
  662.                     elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header (110, 120, 0)
  663.                         log.debug("%s State: Send fax header" % ("*"*20))
  664.                         fax_send_state = FAX_SEND_STATE_SEND_PAGES
  665.  
  666.                         try:
  667.                             ff = file(self.f, 'r')
  668.                         except IOError:
  669.                             log.error("Unable to read fax file.")
  670.                             fax_send_state = FAX_SEND_STATE_ERROR
  671.                             continue
  672.  
  673.                         try:
  674.                             header = ff.read(FILE_HEADER_SIZE)
  675.                         except IOError:
  676.                             log.error("Unable to read fax file.")
  677.                             fax_send_state = FAX_SEND_STATE_ERROR
  678.                             continue
  679.  
  680.                         magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  681.                             resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  682.  
  683.                         if magic != 'hplip_g3':
  684.                             log.error("Invalid file header. Bad magic.")
  685.                             fax_send_state = FAX_SEND_STATE_ERROR
  686.                         else:
  687.                             log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  688.                                       (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  689.  
  690.                             log.debug("Sending fax header...")
  691.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, True, PAGE_FLAG_NEW_DOC)
  692.                             self.create_mfpdtf_fax_header(total_pages)
  693.  
  694.                             try:
  695.                                 self.write_stream()
  696.                             except Error:
  697.                                 log.error("Unable to write to channel.")
  698.                                 fax_send_state = FAX_SEND_STATE_ERROR
  699.  
  700.  
  701.                     elif fax_send_state == FAX_SEND_STATE_SEND_PAGES:  # --------------------------------- Send fax pages state machine (110, 130, 0)
  702.                         log.debug("%s State: Send pages" % ("*"*20))
  703.                         fax_send_state = FAX_SEND_STATE_SEND_END_OF_STREAM
  704.                         page = StringIO()
  705.  
  706.                         for p in range(total_pages):
  707.  
  708.                             if self.check_for_cancel():
  709.                                 fax_send_state = FAX_SEND_STATE_ABORT
  710.  
  711.                             if fax_send_state == FAX_SEND_STATE_ABORT:
  712.                                 break
  713.  
  714.                             try:
  715.                                 header = ff.read(PAGE_HEADER_SIZE)
  716.                             except IOError:
  717.                                 log.error("Unable to read fax file.")
  718.                                 fax_send_state = FAX_SEND_STATE_ERROR
  719.                                 continue
  720.  
  721.                             page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2 = \
  722.                                 self.decode_page_header(header)
  723.  
  724.                             log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" %
  725.                                       (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes))
  726.  
  727.                             page.write(ff.read(bytes_to_read))
  728.                             thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read)
  729.                             page.seek(0)
  730.  
  731.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=PAGE_FLAG_NEW_PAGE)
  732.                             self.create_sop_record(page_num, hort_dpi, vert_dpi, ppr, rpp, encoding)
  733.  
  734.                             try:
  735.                                 data = page.read(RASTER_DATA_SIZE)
  736.                             except IOError:
  737.                                 log.error("Unable to read fax file.")
  738.                                 fax_send_state = FAX_SEND_STATE_ERROR
  739.                                 continue
  740.  
  741.                             if data == '':
  742.                                 log.error("No data!")
  743.                                 fax_send_state = FAX_SEND_STATE_ERROR
  744.                                 continue
  745.  
  746.                             self.create_raster_data_record(data)
  747.                             total_read = RASTER_DATA_SIZE
  748.  
  749.                             while True:
  750.                                 data = page.read(RASTER_DATA_SIZE)
  751.                                 total_read += RASTER_DATA_SIZE
  752.  
  753.                                 dl_state = self.getFaxDownloadState()
  754.                                 if dl_state == pml.UPDN_STATE_ERRORABORT:
  755.                                     fax_send_state = FAX_SEND_STATE_ERROR
  756.                                     break
  757.  
  758.                                 if self.check_for_cancel():
  759.                                     fax_send_state = FAX_SEND_STATE_ABORT
  760.                                     break
  761.  
  762.                                 if data == '':
  763.                                     self.create_eop_record(rpp)
  764.  
  765.                                     try:
  766.                                         self.write_stream()
  767.                                     except Error:
  768.                                         log.error("Channel write error.")
  769.                                         fax_send_state = FAX_SEND_STATE_ERROR
  770.                                     break
  771.  
  772.                                 else:
  773.                                     try:
  774.                                         self.write_stream()
  775.                                     except Error:
  776.                                         log.error("Channel write error.")
  777.                                         fax_send_state = FAX_SEND_STATE_ERROR
  778.                                         break
  779.  
  780.                                 status = self.getFaxJobTxStatus()
  781.                                 while status == pml.FAXJOB_TX_STATUS_DIALING:
  782.                                     self.write_queue((STATUS_DIALING, 0, recipient['fax']))
  783.                                     time.sleep(1.0)
  784.  
  785.                                     if self.check_for_cancel():
  786.                                         fax_send_state = FAX_SEND_STATE_ABORT
  787.                                         break
  788.  
  789.                                     dl_state = self.getFaxDownloadState()
  790.                                     if dl_state == pml.UPDN_STATE_ERRORABORT:
  791.                                         fax_send_state = FAX_SEND_STATE_ERROR
  792.                                         break
  793.  
  794.                                     status = self.getFaxJobTxStatus()
  795.  
  796.                                 if fax_send_state not in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  797.  
  798.                                     while status == pml.FAXJOB_TX_STATUS_CONNECTING:
  799.                                         self.write_queue((STATUS_CONNECTING, 0, recipient['fax']))
  800.                                         time.sleep(1.0)
  801.  
  802.                                         if self.check_for_cancel():
  803.                                             fax_send_state = FAX_SEND_STATE_ABORT
  804.                                             break
  805.  
  806.                                         dl_state = self.getFaxDownloadState()
  807.                                         if dl_state == pml.UPDN_STATE_ERRORABORT:
  808.                                             fax_send_state = FAX_SEND_STATE_ERROR
  809.                                             break
  810.  
  811.                                         status = self.getFaxJobTxStatus()
  812.  
  813.                                 if status == pml.FAXJOB_TX_STATUS_TRANSMITTING:
  814.                                     self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  815.  
  816.                                 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=0)
  817.                                 self.create_raster_data_record(data)
  818.  
  819.                                 if fax_send_state in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  820.                                     break
  821.  
  822.                             page.truncate(0)
  823.                             page.seek(0)
  824.  
  825.  
  826.                     elif fax_send_state == FAX_SEND_STATE_SEND_END_OF_STREAM: # -------------- EOS (110, 140, 0)
  827.                         log.debug("%s State: Send EOS" % ("*"*20))
  828.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  829.                         log.debug("End of stream...")
  830.                         self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, False, PAGE_FLAG_END_STREAM)
  831.  
  832.                         try:
  833.                             self.write_stream()
  834.                         except Error:
  835.                             log.error("Channel write error.")
  836.                             fax_send_state = FAX_SEND_STATE_ERROR
  837.  
  838.                         monitor_state = False
  839.  
  840.  
  841.                     elif fax_send_state == FAX_SEND_STATE_WAIT_FOR_COMPLETE: # -------------- Wait for complete (110, 150, 0)
  842.                         log.debug("%s State: Wait for completion" % ("*"*20))
  843.  
  844.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  845.  
  846.                         time.sleep(1.0)
  847.                         status = self.getFaxJobTxStatus()
  848.  
  849.                         if status == pml.FAXJOB_TX_STATUS_DIALING:
  850.                                 self.write_queue((STATUS_DIALING, 0, recipient['fax']))
  851.                                 log.debug("Dialing ...")
  852.  
  853.                         elif status == pml.FAXJOB_TX_STATUS_TRANSMITTING:
  854.                             self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  855.                             log.debug("Transmitting ...")
  856.  
  857.                         elif status in (pml.FAXJOB_TX_STATUS_DONE, pml.FAXJOB_RX_STATUS_IDLE):
  858.                             fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  859.                             state = STATE_NEXT_RECIPIENT
  860.                             log.debug("Transmitting done or idle ...")
  861.  
  862.                         else:
  863.                             self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  864.                             log.debug("Pending ...")
  865.  
  866.  
  867.                     elif fax_send_state == FAX_SEND_STATE_RESET_TOKEN: # -------------- Release fax token (110, 160, 0)
  868.                         log.debug("%s State: Release fax token" % ("*"*20))
  869.                         self.write_queue((STATUS_CLEANUP, 0, ''))
  870.  
  871.                         try:
  872.                             self.dev.setPML(pml.OID_FAX_TOKEN, '\x00'*16)
  873.                         except Error:
  874.                             log.error("Unable to release fax token.")
  875.  
  876.                         fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
  877.  
  878.  
  879.                     elif fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: # -------------- Close session (110, 170, 0)
  880.                         log.debug("%s State: Close session" % ("*"*20))
  881.                         fax_send_state = FAX_SEND_STATE_DONE
  882.                         log.debug("Closing session...")
  883.  
  884.                         try:
  885.                             mm.close()
  886.                         except NameError:
  887.                             pass
  888.  
  889.                         try:
  890.                             ff.close()
  891.                         except NameError:
  892.                             pass
  893.  
  894.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN:
  895.                             log.debug("Closing fax channel.")
  896.                             self.dev.closeFax()
  897.  
  898.                         self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  899.  
  900.                         time.sleep(1)
  901.  
  902.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN:
  903.                             log.debug("Closing fax channel.")
  904.                             self.dev.closeFax()
  905.  
  906.                         self.dev.close()
  907.  
  908.  
  909.             elif state == STATE_CLEANUP: # --------------------------------- Cleanup (120, 0, 0)
  910.                 log.debug("%s State: Cleanup" % ("*"*20))
  911.  
  912.                 if self.remove_temp_file:
  913.                     log.debug("Removing merged file: %s" % self.f)
  914.                     try:
  915.                         os.remove(self.f)
  916.                         log.debug("Removed")
  917.                     except OSError:
  918.                         log.debug("Not found")
  919.  
  920.                 state = STATE_DONE
  921.  
  922.  
  923.  
  924. # --------------------------------- Support functions
  925.  
  926.  
  927.     def getFaxDownloadState(self):
  928.         result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD)
  929.         if state:
  930.             log.debug("D/L State=%d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  931.             return state
  932.         else:
  933.             return pml.UPDN_STATE_ERRORABORT
  934.  
  935.     def getFaxDownloadError(self):
  936.         result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD_ERROR)
  937.         if state:
  938.             return state
  939.         else:
  940.             return pml.DN_ERROR_UNKNOWN
  941.  
  942.     def getFaxJobTxStatus(self):
  943.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_TX_STATUS)
  944.         if status:
  945.             log.debug("Tx Status=%d (%s)" % (status, pml.FAXJOB_TX_STATUS_STR.get(status, 'Unknown')))
  946.             return status
  947.         else:
  948.             return pml.FAXJOB_TX_STATUS_IDLE
  949.  
  950.     def getFaxJobRxStatus(self):
  951.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_RX_STATUS)
  952.         if status:
  953.             log.debug("Rx Status=%d (%s)" % (status, pml.FAXJOB_RX_STATUS_STR.get(status, 'Unknown')))
  954.             return status
  955.         else:
  956.             return pml.FAXJOB_RX_STATUS_IDLE
  957.  
  958.     def getCfgUploadState(self):
  959.         result_code, state = self.dev.getPML(pml.OID_DEVICE_CFG_UPLOAD)
  960.         if state:
  961.             log.debug("Cfg Upload State = %d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  962.             return state
  963.         else:
  964.             return pml.UPDN_STATE_ERRORABORT
  965.  
  966.     def create_mfpdtf_fixed_header(self, data_type, send_variant=False, page_flags=0):
  967.         header_len = FIXED_HEADER_SIZE
  968.  
  969.         if send_variant:
  970.             if data_type == DT_DIAL_STRINGS:
  971.                     header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
  972.  
  973.             elif data_type == DT_FAX_IMAGES:
  974.                 header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
  975.  
  976.         self.stream.write(struct.pack("<IHBB",
  977.                           0, header_len, data_type, page_flags))
  978.  
  979.  
  980.     def create_mfpdtf_dial_strings(self, number):
  981.         p = struct.pack("<BBHH51s",
  982.                           MAJOR_VER, MINOR_VER,
  983.                           1, 51, number[:51])
  984.         log.debug(repr(p))
  985.         self.stream.write(p)
  986.  
  987.  
  988.     def adjust_fixed_header_block_size(self):
  989.         size = self.stream.tell()
  990.         self.stream.seek(0)
  991.         self.stream.write(struct.pack("<I", size))
  992.  
  993.  
  994.     def create_sop_record(self, page_num, hort_dpi, vert_dpi, ppr, rpp, encoding, bpp=1):
  995.         self.stream.write(struct.pack("<BBHHHIHHHHHHIHHHH",
  996.                             RT_START_PAGE, encoding, page_num,
  997.                             ppr, bpp,
  998.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi,
  999.                             ppr, bpp,
  1000.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi))
  1001.  
  1002.  
  1003.     def create_eop_record(self, rpp):
  1004.         self.stream.write(struct.pack("<BBBBII",
  1005.                             RT_END_PAGE, 0, 0, 0,
  1006.                             rpp, 0,))
  1007.  
  1008.  
  1009.     def create_raster_data_record(self, data):
  1010.         assert len(data) <= RASTER_DATA_SIZE
  1011.         self.stream.write(struct.pack("<BBH",
  1012.                         RT_RASTER, 0, len(data),))
  1013.         self.stream.write(data)
  1014.  
  1015.  
  1016.     def create_mfpdtf_fax_header(self, total_pages):
  1017.         self.stream.write(struct.pack("<BBBHBI20s20s20sI",
  1018.                             MAJOR_VER, MINOR_VER, SRC_HOST, total_pages,
  1019.                             TTI_PREPENDED_TO_IMAGE, 0, '', '', '', 0))
  1020.  
  1021.  
  1022.     def write_stream(self):
  1023.         self.adjust_fixed_header_block_size()
  1024.         self.dev.writeFax(self.stream.getvalue())
  1025.         self.stream.truncate(0)
  1026.         self.stream.seek(0)
  1027.